using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Threading.Tasks;
using IdentityModel;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;

namespace WebBClient
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //http 下 登录成功后跳转 http://localhost:port/signin-oidc 时 服务器500错误, 同时 app.UseCookiePolicy(); 不要忘记写
            //services.Configure<CookiePolicyOptions>(options =>
            //{
            //    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            //    options.CheckConsentNeeded = context => true;
            //    options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.Lax;
            //});
            services.ConfigureNonBreakingSameSiteCookies();


            //不知道干什么的, 有的网站有这行, 
            //该标志的默认值，该标志确定是否使用InboundClaimTypeMap。
            //JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
            //https://blog.lcrun.com/wei-shi-yao-yao-shi-yong-jwtsecuritytokenhandler-defaultinboundclaimtypemap-clear/
            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

            services.AddControllers();


            #region IdentityServer4--Implicit (教程里的)
            //要添加IdentityServer4.AccessTokenValidation.dll
            //services.AddAuthentication("Bearer")
            //    .AddIdentityServerAuthentication(options =>
            //    {
            //        options.Authority = "http://localhost:5000";
            //        options.ApiName = "api1";
            //        options.RequireHttpsMetadata = false;
            //    });
           
            #endregion

            services.AddAuthentication(options =>
                {
                    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
                })
                .AddIdentityServerAuthentication(options =>
                {
                    //这个方法同时支持了 Reference Token 和 JWT 的认证，  https://www.cnblogs.com/stulzq/p/13095412.html
                    options.Authority = "http://localhost:5000";
                    options.ApiName = "api1";
                    options.RequireHttpsMetadata = false;
                })
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
                {
                    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    options.Authority = "http://localhost:5000";
                    options.RequireHttpsMetadata = false;
                    options.ClientId = "mvc client b";

                    //options.ClientSecret = "mvc secret"; //不需要这个,就算 idp配置了,这里也不用配置,因为是账号密码登陆的 
                    options.SaveTokens = true;
                    options.ResponseType = OpenIdConnectResponseType.Code;

                    options.SaveTokens = true;//允许中间件保存它从身份提供者接收的令牌，以便我们以后可以轻松地使用它们
                    options.GetClaimsFromUserInfoEndpoint = true; //启用从用户信息终结点获取有关当前用户的声明,  棕南哪里要添加(也不知道要不要)
                });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            // 在任何其他可能编写cookie的中间件之前添加此项
            app.UseCookiePolicy();//使上面的services.Configure<CookiePolicyOptions>生效
          
            app.UseAuthentication(); //需要这行 自动跳转到登陆页

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();//必须先使用 UseAuthentication 再使用 UseAuthorization
            
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}
